﻿Imports System.Collections.ObjectModel
Imports System.Reflection
Imports System.Collections.Specialized

''' <summary>
''' 読み込み可能リスト
''' </summary>
''' <typeparam name="T"></typeparam>
''' <remarks>
''' </remarks>
Public Class LoadableList(Of T)
    Inherits ObservableCollection(Of T)
    Implements ILoadableList

    Public Sub New(parentInstance As Object, parentProp As PropertyInfo)
        _parentInstance = parentInstance
        _parentProp = parentProp
    End Sub

    ''' <summary>
    ''' ローダー
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    Friend Property Loader As Loader
        Get
            Return Me.Query.Provider.Loader
        End Get
        Set(value As Loader)
            Me.Query.Provider.Loader = value
        End Set
    End Property

    ''' <summary>
    ''' クエリ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Query As Query(Of T)

    ''' <summary>
    ''' クエリを代入します
    ''' </summary>
    ''' <param name="query"></param>
    ''' <remarks></remarks>
    Private Sub SetQuery(query As IQuery) Implements ILoadableList.SetQuery
        Me.Query = query
    End Sub

    ''' <summary>
    ''' コレクションを取得します
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Fetch() Implements ILoadableList.Fetch
        If Me.IsFetched Then Return
        If Me.Loader.Connection.State = ConnectionState.Closed Then Throw New InvalidOperationException

        _isFetched = True

        Me.Query.ToList()
    End Sub

    Private _isFetched As Boolean = False
    ''' <summary>
    ''' 取得済みかどうかを示します
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property IsFetched As Boolean Implements ILoadableList.IsFetched
        Get
            Return If(Me.Any OrElse _isFetched, True, False)
        End Get
    End Property

    Private _parentInstance As Object
    ''' <summary>
    ''' 親インスタンス
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ParentInstance As Object
        Get
            Return _parentInstance
        End Get
    End Property

    Private _parentProp As Object
    ''' <summary>
    ''' 親プロパティ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ParentProp As PropertyInfo
        Get
            Return _parentProp
        End Get
    End Property

    Private Sub LoadableList_CollectionChanged(sender As Object, e As Specialized.NotifyCollectionChangedEventArgs) Handles Me.CollectionChanged
        '#120 LoadableListActivatorが遅い
        '無意味に複雑化していたコードを見直し。ParentBinder.vbを削除。
        If e Is Nothing Then Throw New ArgumentNullException("e")

        If e.Action <> NotifyCollectionChangedAction.Add Then Return
        If Me.ParentProp Is Nothing Then Return

        For Each newItem In e.NewItems
            '追加された場合、親プロパティに親インスタンスを代入する
            Me.ParentProp.SetValue(newItem, Me.ParentInstance, Nothing)
        Next
    End Sub
End Class
